package com.zjw.zy.utils.outdepend;

import androidx.annotation.NonNull;

import com.zjw.zy.constant.SpecialDay;
import com.zjw.zy.utils.ToastUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 计算公式：[Y*D+C]-L
 * <p>
 * 二十四节气计算
 */
public class SolarTermUtils {
    /**
     * 节气D值
     */
    private static final double D = 0.2422;
    /**
     * 20世纪的节气C值
     */
    private static final double[] C_20 = {6.11, 20.84, 4.6295, 19.4599, 6.3826, 21.4155, 5.59, 20.888, 6.318, 21.86,
            6.5, 22.2, 7.928, 23.65, 8.35, 23.95, 8.44, 23.822, 9.098, 24.218, 8.218, 23.08, 7.9, 22.6};
    /**
     * 21世纪的节气C值
     */
    private static final double[] C_21 = {5.4055, 20.12, 3.87, 18.73, 5.63, 20.646, 4.81, 20.1, 5.52, 21.04, 5.678,
            21.37, 7.108, 22.83, 7.5, 23.13, 7.646, 23.042, 8.318, 23.438, 7.438, 22.36, 7.18, 21.94};

    /**
     * 24节气
     */
    private static final String[] TERM = {
            SpecialDay.SolarTerm.XIAO_HAN,
            SpecialDay.SolarTerm.GREAT_COLD,
            SpecialDay.SolarTerm.BEGINNING_OF_SPRING,
            SpecialDay.SolarTerm.RAINWATER,
            SpecialDay.SolarTerm.WAKING_INSECTS,
            SpecialDay.SolarTerm.VERNAL_EQUINOX,
            SpecialDay.SolarTerm.QING_MING,
            SpecialDay.SolarTerm.GRAIN_RAIN,
            SpecialDay.SolarTerm.BEGINNING_OF_SUMMER,
            SpecialDay.SolarTerm.XIAO_MAN,
            SpecialDay.SolarTerm.AWN_SEED,
            SpecialDay.SolarTerm.SUMMER_SOLSTICE,
            SpecialDay.SolarTerm.SUNSTROKE,
            SpecialDay.SolarTerm.GREAT_HEAR,
            SpecialDay.SolarTerm.BEGINNING_OF_AUTUMN,
            SpecialDay.SolarTerm.HEAT_TREATMENT,
            SpecialDay.SolarTerm.WHITE_DEW,
            SpecialDay.SolarTerm.AUTUMN_EQUINOX,
            SpecialDay.SolarTerm.COLD_DEW,
            SpecialDay.SolarTerm.FROST,
            SpecialDay.SolarTerm.BEGINNING_OF_WINTER,
            SpecialDay.SolarTerm.LIGHT_SNOW,
            SpecialDay.SolarTerm.HEAVY_SNOW,
            SpecialDay.SolarTerm.WINTER_SOLSTICE,
    };

    /**
     * 节气缓存表
     */
    private static final Map<Integer, Map<String, String>> termMap = new HashMap<>();

    /**
     * 获取指定日期节气名称
     *
     * @param year:
     * @param month:
     * @param date:
     * @return
     */
    @NonNull
    public static String getTermName(int year, int month, int date) {
        Map<String, String> map = getYearTermMap(year);
        if (map == null || map.isEmpty()) {
            return "";
        }
        String s = map.get(getTermKey(month, date));
        return s == null ? "" : s;
    }

    /**
     * 获取指定年份萨拉表
     *
     * @param year:
     * @return
     */
    public static Map<String, String> getYearTermMap(int year) {
        // 处理世纪C值
        double[] c;
        if (year > 1900 && year <= 2000) {
            c = C_20;
        } else if (year > 2000 && year <= 2100) {
            c = C_21;
        } else {
            ToastUtils.showLong("不支持的年份:" + year + ",目前只支持1901年到2100年的时间范围");
            return null;
        }
        // 从节气表中取
        Map<String, String> map = termMap.get(year);
        if (map != null) {
            return map;
        }
        // 节气表中无对应的节气数据，则计算生成
        synchronized (TERM) {
            map = termMap.get(year);
            if (map == null) {
                int y = year % 100;
                map = new HashMap<>();
                for (int k = 0; k < 24; k++) {
                    // 计算节气日期，计算公式：[Y*D+C]-L
                    int date = 0;
                    if (k < 2 || k > 22) {
                        date = (int) (y * D + c[k]) - (int) ((y - 1) / 4);
                    } else {
                        date = (int) (y * D + c[k]) - (int) (y / 4);
                    }
                    // 记录计算结果
                    map.put(getTermKey(k / 2 + 1, date), TERM[k]);
                }
                // 计算结果添加到节气表
                termMap.put(year, map);
            }
        }
        return map;
    }

    /**
     * 组装节气存储key
     *
     * @param month
     * @param date
     * @return
     */
    private static String getTermKey(int month, int date) {
        String key = String.valueOf(month);
        if (month < 10) {
            key = "0" + key;
        }
        if (date < 10) {
            key += "0";
        }
        key += date;
        return key;
    }
}